﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TELOS_Konverter
{
    class SmiHandler
    {
        StringHandler sth = new StringHandler();
        FileOperations fo = new FileOperations();
        MessageHandler mh = new MessageHandler();
        ErrorHandler eh = new ErrorHandler();

        /// <summary>
        /// <para>As we don't have a valid SMI file for WMP, we have to write a new one. This includes a lot of header stuff</para><br />
	    /// <para>and real meta data like CSS and the actual Transcript</para>
        /// </summary>
        /// <returns>True if the writing process ended successfully, false otherwise</returns>
        public bool writeSMIFile()
        {
            // access the real media text file
            String fName = fo.getRMTextFilePath();
            String header = "<SAMI>\n<HEAD>\n   <STYLE TYPE=\"Text/css\">\n   <!--\n      P {\n        margin-left: 5pt;\n        margin-right: 5pt;\n        font-size: 10pt;\n        text-align: center;\n        font-family: Arial,Tahoma;\n        font-weight: plain;\n        color: #FFFFFF;\n        background-color: #000000;\n      }\n      .SUBTTL {Name: 'Subtitles'; Lang: en-US; SAMIType: CC;}\n   -->\n   </STYLE>\n</HEAD>\n\n<BODY>\n";
            List<string> fileLines = new List<string>(fo.readFile(fName));
            List<string> outputLines = new List<string> { "" };

            // Write each turn into a list
            for (int i = 0; i < fileLines.Count - 3; i++)
            {
                // exit criterion
                if (fileLines[i].IndexOf("</font>") >= 0)
                {
                    break;
                }
                else
                {
                    outputLines.Add(createTurn(fileLines, i));
                }
            }
            
            // I have no idea what's going on here, but we need these two and the later "-1" in the for loop :-(
            try
            {
                outputLines.RemoveAt(outputLines.Count - 1);
                outputLines.RemoveAt(outputLines.Count - 2);
            }
            catch (Exception e)
            {
                mh.displayError(e);
            }

            String bottom = "\n</BODY>\n</SAMI>";

            String fileContent = header;

            // add all lines to the content
            for (int i = 0; i < outputLines.Count - 1; i++)
            {
                fileContent = fileContent + outputLines[i];
            }

            fileContent = fileContent + bottom;
            // Note:
            // getSAMIFilePath() containts the address on the web server and not the address on the media server
            return fo.writeFile(fo.getSAMILocalFilePath(), fileContent.Split('\n').ToList(), fo.getANSI());
            // ("Trying to write file: \n" + fo.getSAMILocalFilePath());
            //return true;
        }

        /**getASXStartTime
         * @param: asx file name
         * @return: the start time of the video, as integer
         * The start time is in the original smi file, together with the clip end time
         */
        private double getASXStartTime()
        {
            return FileOperations.asxStartTime;
        }

        /**convertTime
         * @param: start time and current time stamp time
         * @return: new current time
         * Calculates new current time by adding the start time to the current time
         */
        private String convertTime(double videoStart, double currentTime)
        {
            return ((videoStart + currentTime + getASXStartTime()) * 1000).ToString();
        }

        /**getTurnSpeech
         * @param: line number, or rather the turn number as the line is +3 from each turn
         * @return: the string that contains the actual speech
         * This function deletes the meta stuff from each line and returns only the spoken words
         */
        private String getTurnSpeech(List<string> list, int turn)
        {
            return sth.delete(list[turn + 3], "<clear/>", new List<string> { "before", "include" }).Replace("’", "'");
        }

        /**getTurnTime
         * @param: line number, or rather the turn number, as the line is +3 from each turn
         * @return: integer that contains the begin of the turn
         */
        private double getTurnTime(List<string> list, int turn)
        {
            // error:
            try
            {
                string cache = list[turn + 3];
                cache = sth.delete(cache, "begin=\"", new List<string> { "before", "include" });
                cache = sth.delete(cache, "\"/><clear/>", new List<string> { "after", "include" });
                cache = cache.Replace(".", ",");
                if (!cache.Equals(""))
                    return Double.Parse(cache);
                else
                    return 0;
            }
            catch (Exception e)
            {
                eh.createError(e);
                return 0;
            }
        }

        /**createTurn
         * @param: - the complete transcript
         *         - line number, or rather the turn number, as the line is +3 from each turn number
         * @return: String that contains all meta data for each turn
         * Core function to write content to the new SMI file including all meta information and the actual words of the turns
         */
        private String createTurn(List<string> list, int turn)
        {
            return "  <sync start=" + Double.Parse(convertTime(0, getTurnTime(list, turn)).ToString()) + ">\n    <p>" + getTurnSpeech(list, turn) + "</p>\n  </sync>\n";
        }
    }
}
